
var ProjectSchedule = function (project) {
  this.project = project
  this.init()
}
ProjectSchedule.prototype = {

  init: function () {
    var me = this
    var project = me.project

    project.allowOrderProject = false // 阻止默认排程计算
    project.scheduleEnabled = false // 阻止默认调度模块

    project.on('cellbeginedit', this.onCellBeginEdit, this)
    project.on('aftercellcommitedit', this.onCellCommitEdit, this)
    project.on('itemdragstart', this.onItemDragStart, this)
    project.on('itemdragcomplete', this.onItemDragComplete, this)
    project.on('dodragdrop', this.onDoTaskDragDrop, this)
  },

  onDoTaskDragDrop: function (e) {
    var dragRecords = e.tasks; var targetRecord = e.targetTask; var action = e.action
    this.project.moveTasks(dragRecords, targetRecord, action)
  },

  onCellBeginEdit: function (e) {
    var task = e.record; var field = e.field
    if (field == 'Finish') {
      e.cancel = true
    }

    if (field == 'Start' ||
            field == 'ActualStart' || field == 'ActualFinish' ||
            field == 'ConstraintDate'
    ) {
      if (!mini.isDate(e.value) && e.editor) {
        e.editor.setViewDate(e.sender.getStartDate())
      }
    }
  },

  onCellCommitEdit: function (e) {
    e.cancel = true
    var task = e.record; var field = e.field; var value = e.value; var oldValue = task[field]; var column = e.column

    if (mini.isEquals(oldValue, value)) return
    try {
      if (field == 'Start') {
        this.setTaskStart(task, value)
      } else if (field == 'Duration') {
        this.setTaskDuration(task, value)
      } else if (field == 'PlanStart') {
        alert(1)
      } else if (field == 'PlanFinish') {
        alert(2)
      } else {
        if (column.displayField) {
          var o = {}
          o[column.field] = e.value
          o[column.displayField] = e.text
          this.project.updateTask(task, o)
        } else {
          this.project.updateTask(task, field, value)
        }
      }
    } catch (ex) {
      alert(ex.message)
    }
  },

  onItemDragStart: function (e) {
    if (e.action == 'move' || e.action == 'finish') {
      e.cancel = true
    }
  },

  onItemDragComplete: function (e) {
    var action = e.action; var value = e.value; var task = e.item
    if (action == 'start') {
      this.setTaskStart(task, value)
    }
  },

  setTaskStart: function (task, value, order) {
    var me = this
    var project = me.project

    project.tasks.updateRecord(task, 'Start', value)
    if (mini.isDate(task.Start)) {
      task.Start = project.getWorkingDateByCalendar(task.Start, true)

      if (task.Finish) {
        task.Duration = project.getDurationByCalendar(task.Start, task.Finish)
        project.setTaskModified(task, 'Duration')
      }
    }

    if (order !== false) {
      me.orderProject(task)
    }
  },

  setTaskDuration: function (task, value) {
    var me = this
    var project = me.project

    var days = parseInt(value)
    if (!mini.isNumber(days)) return
    if (days < 0) days = 0

    project.tasks.updateRecord(task, 'Duration', value)
    if (mini.isDate(task.Finish)) {
      task.Start = project.getStartByCalendar(task.Finish, task.Duration)
      project.setTaskModified(task, 'Start')
    }

    me.orderProject(task)
  },

  suspendOrder: false, // 挂起排程
  orderProject: function (task) {
    var me = this
    var project = me.project
    if (me.suspendOrder) return
    if (!task) throw new Error('orderProject task is null')

    if (me.ordering) throw new Error('orderProject loop')
    me.ordering = true

    var children = task.children
    var isSummary = task.Summary && children
    var start = task.Start

    if (!start) return

    if (isSummary) {
      // 将子任务开始日期设置为父任务开始日期
      for (var i = 0, l = children.length; i < l; i++) {
        var child = children[i]
        var value = new Date(start.getTime())
        me.setTaskStart(child, value, false)
      }
    } else {
      // 得到最早子任务开始日期，设置给父任务
      var parentTask = project.getParentTask(task)
      if (!parentTask) return

      var minStart
      children = parentTask.children
      for (var i = 0, l = children.length; i < l; i++) {
        var child = children[i]
        if (child.Start) {
          if (!minStart || minStart.getTime() > child.Start.getTime()) {
            minStart = new Date(child.Start.getTime())
          }
        }
      }
      if (minStart) me.setTaskStart(parentTask, minStart, false)
    }

    me.ordering = false

    project.orderProject()
  }

}
